
using UnityEngine;
using System.Collections;
//using System.Collections.Generic;

public class Spawner : MonoBehaviour 
{
	private static Spawner mInstance;
	public static Spawner Instance() {return mInstance;}

	public int totalWaves;
	public static int totalEnemeies;
    public static int waveEnemies;
	private bool showWaveMsg = false;
    private float GuiOffsetX = 3;
    private float GuiOffsetY = -434.2f;
	private float GuiOffsetX2 = 0;
	private float GuiOffsetY2 = 68.3f;
    private float GuiOffsetW = 100f+15f;
    private float GuiOffsetH = 25.6f;
	private float GuiOffsetW2 = 100f+15f;
    private float GuiOffsetH2 = 25.6f;
    public static int currWave = -1;
    public float Range = 10;
	public GUIStyle customGuiStyle;
    GameObject toSpawn;
	public float WaveMessageLocX = 0;
	public float WaveMessageLocY = 0;
	float t;
	private bool doOnce = true;
    private GameObject parent;
	void Awake()
	{
		if(!mInstance)
			mInstance = this;

	}
	
	[System.Serializable]
	public class Collection
	{
        public string enemy = "Enemy";
		public GameObject obj;
		public int Count;
	}
	
	[System.Serializable]
	public class Wave
	{
        public string WaveName = "Wave";
        public string WaveMessage = "Put Wave Message Here";
		public float TimeBetweenSpawns = .75f;
		public Collection[] objects;
	}
	
	public Wave[] waves;
	private int EnemyReferenceCounter;
	public bool IsSpawning {get;set;}
	
	public void ShipDead()
	{
//		if(--EnemyReferenceCounter <= 0)
//		{
//			EnemyReferenceCounter = 0;
//			if(!IsSpawning)
//				DoSpawn(++currWave);
//		}
	}
	
    void Start()
    {

		if(doOnce)
		{
       		parent = new GameObject("Spawned Enemies");
       		parent.gameObject.tag = "Spawned";
			doOnce = false;
		}
        currWave = -1;
        totalWaves = waves.Length;
        totalEnemeies = 0;
        waveEnemies = enemyCount(currWave + 1);
        if (PlayerPrefs.HasKey("Level"))
        {
            currWave = PlayerPrefs.GetInt("Level") - 1;
        }
		showWaveMsg = true;
		//print ( waves[0].WaveMessage);
        DoSpawn(++currWave);
    }

	public void DoSpawn(int wavenum)
	{
        waveEnemies = enemyCount(); 
		if(wavenum < waves.Length)
			StartCoroutine(Spawn(wavenum));
	}
	
	IEnumerator Spawn(int wavenum)
	{
        GameObject child;
       GameObject city = GameObject.FindGameObjectWithTag("city").transform.GetChild(0).gameObject;
        //GameObject city = GameObject.FindGameObjectWithTag("city");
		IsSpawning = true;

       // Debug.Log("spawning)");
		while(IsSpawning)
		{
			yield return new WaitForSeconds(waves[wavenum].TimeBetweenSpawns);
			int look = 0;
            while (look < waves[wavenum].objects.Length && waves[wavenum].objects[look].Count <= 0)
            {
                ++look;
            }
            if(look >= waves[wavenum].objects.Length)
			{
         //       print("here");
				//Wave is over, break
				break;
			}
			++EnemyReferenceCounter;
          
			toSpawn = waves[wavenum].objects[look].obj;
            MeshFilter viewedModelFilter = (MeshFilter)toSpawn.GetComponent("MeshFilter");
            Vector3 enemySize = viewedModelFilter.sharedMesh.bounds.size * toSpawn.transform.localScale.x;
            float minX = WithinBounds.Bounds.minX + 1*(enemySize.x);
            float maxX = WithinBounds.Bounds.maxX - 2*(enemySize.x);
//            print("size " + WithinBounds.Bounds.minX + " " + WithinBounds.Bounds.maxX);
//            print(minX + " " + maxX);

            float spawnX = Random.Range(minX, maxX);
 //           print(spawnX);
            --waves[wavenum].objects[look].Count;
            if (toSpawn.tag.StartsWith("Boss")) 
            {
                Debug.Log("boss spawned");
                city.SetActive(false);
               child = (GameObject)Instantiate(toSpawn, new Vector3(0, 5f, 0), toSpawn.transform.rotation);
            //   child = (GameObject)Instantiate(toSpawn, new Vector3(0, transform.position.y, 0), toSpawn.transform.rotation);
				            }
            else
            {           
                child = (GameObject) Instantiate(toSpawn, new Vector3(spawnX, transform.position.y, 0), toSpawn.transform.rotation);
            }
                child.transform.parent = parent.transform;
		}
		//IsSpawning = false;
	}
    int enemyCount()
    {
        return enemyCount(currWave);
    }
    int enemyCount(int currWave)
    {
        int enemies = 0;
        foreach (Collection enemy in waves[currWave].objects)
        {
            enemies += enemy.Count;
        }
        return enemies;
    }
	void Update()
	{
		if (waveEnemies == 0 && currWave != totalWaves && totalWaves > 1)// && enemyCount()==0)
        {
            PlayerPrefs.SetInt("Level", currWave + 1);
			showWaveMsg = true;
            DoSpawn(++currWave);
        }
        else if(currWave == totalWaves && waveEnemies == 0 || totalWaves ==1 && waveEnemies == 0)
        {
            Debug.Log ("You got past all the enemies you win!");
            Manager.Win();
			Destroy(this);
			
        }
	}
	void TurnOffWaveMsg()
	{
		showWaveMsg = false;
	}
	void OnGUI()
	{
		waveEnemies = enemyCount() + parent.transform.childCount;
		if(showWaveMsg)
		{
			//GUI.Label(new Rect(Screen.width/2 + WaveMessageLocX, Screen.height/2 + WaveMessageLocY, 500, 50), waves[currWave].WaveMessage);
						//GUI.Label(new Rect(Screen.width/2, Screen.height/2 , 500, 50), waves[currWave].WaveMessage);

			Invoke("TurnOffWaveMsg",2f);
		}
	    GUI.Label(new Rect(Screen.width/GuiOffsetX, Screen.height / GuiOffsetY, GuiOffsetW, GuiOffsetH), " Wave: "+ (currWave+1).ToString(),Camera.main.GetComponent<Currency>().myCustomGUIStyle);
        GUI.Label(new Rect(Screen.width - GuiOffsetW2*1.6f, Screen.height / GuiOffsetY, GuiOffsetW2, GuiOffsetH2), "Enemies: " + waveEnemies.ToString(), Camera.main.GetComponent<Currency>().myCustomGUIStyle);
	}
}
